/*
 * memory.c
 *
 *  Created on: Jan 21, 2013
 *      Author: Ian Smith, Travis Drake
 */

#include "memory.h"
#include "random.h"

/*
 * Initializes a new memory bank.
 */
MemoryPtr Memory_newMemory(void)
{
	MemoryPtr mem_ptr = (MemoryPtr)malloc(sizeof(MemoryStr));
	return mem_ptr;
}

/*
 * Sets the address at which the next read or write will occur.
 * memory: A pointer to the memory to modify.
 * value: The new value to set.
 */
void Memory_setMemoryAddressRegister(MemoryPtr memory, unsigned short value)
{
	memory->mar = value;
}

/*
 * Sets the data to be written to memory.
 * memory: A pointer to the memory to modify.
 * value: The new value to set.
 */
void Memory_setMemoryDataRegister(MemoryPtr memory, Byte value)
{
	memory->mdr = value;
}

/*
 * Gets the data most recently read from memory.
 * memory: A pointer to the memory to query.
 */
Byte Memory_getMemoryDataRegister(MemoryPtr memory)
{
	return memory->mdr;
}

/*
 * Gets the value at the memory address stored in the MAR and puts it in the MDR
 * This operation is undefined if the address register hasn't been set.
 * memory: A pointer to the memory to query.
 */
void Memory_performRead(MemoryPtr memory)
{
	memory->mdr = memory->mem_block[memory->mar];
}

/*
 * Sets the value at the memory address stored in MAR to the value in MDR.
 * This operation is undefined if the address register or the
 * data register hasn't been set.
 */
void Memory_performWrite(MemoryPtr memory)
{
	memory->mem_block[memory->mar] = memory->mdr;
}

/*
 * Initializes the memory block to all random values.
 * memory: The memory to initialize.
 */
void Memory_initialize(MemoryPtr memory)
{
	int i;
	for (i = 0; i < MEMORY_SIZE_BYTES; i++)
	{
		Byte value = random_byte();
		Memory_setMemoryAddressRegister(memory, i);
		Memory_setMemoryDataRegister(memory, value);
		Memory_performWrite(memory);
	}
}

/*
 * Frees the memory object from system memory.
 * memory: The memory to delete.
 */
void Memory_deleteMemory(MemoryPtr memory)
{
	free(memory);
}
